Java导出word文档

您所在的位置:网站首页 word 导出 Java导出word文档

Java导出word文档

2023-09-27 19:09| 来源: 网络整理| 查看: 265

需求

在开发中,经常会碰到需要导出word文档的时候,比如一些审批表、财务报表等等,接下来介绍一种基于java的简单高效的转换方法

环境 依赖

Apache的POI、FreeMarker和XDocreport

项目

Springboot项目

模板引擎

使用FreeMarker生成Word模板,通过${}占位符来进行关键词替换,如在word模板中用 ${city} 来替换 深圳市之类的

编辑器

Word或者WPS,这两个编辑器会有一点点差异(不大),下面会详细介绍

pom依赖 org.apache.poi poi 3.15 org.apache.poi poi-ooxml 3.15 fr.opensagres.xdocreport fr.opensagres.xdocreport.core 2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.document 2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.template 2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.document.docx 2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.template.freemarker 2.0.2 Word模板

我们先创建一个模板,模板如下,word模板只能是docx文件,doc文件不支持,会报错。 在这里插入图片描述 这里特意说明一下WPS和Word这两个编辑工具的区别,我发现用WPS创建的模板不需要加域也能被识别替换,而用Word就必须要加域才能识别。

因为FreeMarker模板是通过 ${变量名} 来识别并进行替换的,WPS创建的模板解析成xml文件时,会自动把 ${变量名} 当成一个整体来解析,Word则会进行拆分,所以需要通过域来合并成一个整体。但是不管Word还是WPS,最好还是都加上域比较好,这样不会出意外。

先说一下如何创建域,首先在鼠标光标出按住 ctrl + F9,这时候会出现一对尖括号“《》”(也可能是花括号“{}”,不要惊讶,两种效果一样),然后在尖括号(或花括号)里面右键鼠标–》编辑域 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 如果你想根据列表自动生成表格,你得先创建一个表格,像我这个模板中的用户表,然后按照上面一样的方法添加域,结果如下: 在这里插入图片描述

现在模板准备好了,我们来看看后端代码:

因为需要列表,所以我们先创建一个user对象

public class User{ private Integer id; private Integer age; private String name; private String address; private String pas; private String description; }

测试代码

import com.orz.entity.User; import fr.opensagres.xdocreport.core.XDocReportException; import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.template.IContext; import fr.opensagres.xdocreport.template.TemplateEngineKind; import fr.opensagres.xdocreport.template.formatter.FieldsMetadata; public class Test { private static final Logger logger = LoggerFactory.getLogger(Test.class); @Test public void exportWord(){ InputStream in = null; FileOutputStream out =null; try { //获取本地目录的word模板 in = new FileInputStream(new FileOutputStream(new File("D://用户模板.docx"))); //注册xdocreport实例并加载FreeMarker模板引擎 IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker); //创建xdocreport上下文对象 IContext context = report.createContext(); List users = new ArrayList(); users.add(new User(1,10,"你好","上海","KONO DIO DA","描述")); users.add(new User(2,18,"张三","北京","12957451","描述")); users.add(new User(3,20,"李四","武汉","个爱搜纪委","描述")); users.add(new User(4,25,"王五","广州","没出息捏","描述")); users.add(new User(5,25,"赵六","深圳","群殴IU为居民","描述")); users.add(new User(6,22,"钱七","杭州","IU前往合肥南","描述")); //将需要替换的数据数据添加到上下文中 //其中key为word模板中的域名,value是需要替换的值 context.put("author","敬亭山"); context.put("date","2022年8月19日"); context.put("users",users); //创建字段元数据,需要表格才加下面这两行,否则不用 FieldsMetadata fm = report.createFieldsMetadata(); //Word模板中的表格数据对应的集合类型 fm.load("users", User.class, true); //输出到本地目录 out = new FileOutputStream(new File("D://用户模板导出.docx")); //处理word文档并输出 report.process(context, out); } catch (IOException e) { logger.error("读取Word模板异常",e); } catch (XDocReportException e) { logger.error("word模板生成失败",e); } finally { if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

直接运行测试一下,生成的结果如下: 在这里插入图片描述 结果和预期的一样,很完美。

增强

可能有些小伙伴也需要导出图片,图片就不需要域了,需要添加书签,下面我们来创建一个图片模板 在这里插入图片描述 在这里插入图片描述 依次添加所有书签,我这有3张图,就是3个书签,每张图要单独添加书签!,添加完的结果如下: 在这里插入图片描述 接着看一下代码实现

import fr.opensagres.xdocreport.core.XDocReportException; import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.template.IContext; import fr.opensagres.xdocreport.template.TemplateEngineKind; import fr.opensagres.xdocreport.template.formatter.FieldsMetadata; public class Test { private static final Logger logger = LoggerFactory.getLogger(Test.class); @Test public void exportWordImage(){ InputStream in = null; FileOutputStream out =null; try { in = new FileInputStream(new File("D:\\图片模板.docx")); //注册xdocreport实例并加载FreeMarker模板引擎 IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker); //创建xdocreport上下文对象 IContext context = report.createContext(); //创建字段元数据 FieldsMetadata fm = report.createFieldsMetadata(); //Word模板中的表格数据对应的集合类型 fm.addFieldAsImage("one"); fm.addFieldAsImage("two"); fm.addFieldAsImage("three"); InputStream one= new FileInputStream(new File("D://其他文件//图片//1.jpeg")); InputStream two= new FileInputStream(new File("D://其他文件//图片//2.jpeg")); InputStream img3 = new FileInputStream(new File("D://其他文件//图片//3.jpeg")); context.put("one",one); context.put("two",two); context.put("three",three); //输出到本地目录 out = new FileOutputStream(new File("D://图片模板导出.docx")); report.process(context, out); img3.close(); img2.close(); img1.close(); } catch (IOException e) { logger.error("读取Word模板异常",e); } catch (XDocReportException e) { logger.error("word模板生成失败",e); } finally { if(out!=null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

直接运行测试一下,看看结果: 在这里插入图片描述 结果很完美,成功导出来了。

以上就是全部内容了,完结撒花✿✿ヽ(°▽°)ノ✿✿


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3